home *** CD-ROM | disk | FTP | other *** search
- /*LINTLIBRARY*/
-
- /* @(#)x11.c 1.26 91/11/13
- *
- * X11 dependent graphics routines used by reve.
- *
- * Copyright (c) 1990, 1991 - Rich Burridge & Yves Gallot.
- * All rights reserved.
- *
- * Permission is granted to copy this source, for redistribution
- * in source form only, provided the news headers in "substantially
- * unaltered format" are retained, the introductory messages are not
- * removed, and no monies are exchanged.
- *
- * Permission is also granted to copy this source, without the
- * news headers, for the purposes of making an executable copy by
- * means of compilation, provided that such copy will not be used
- * for the purposes of competition in any othello tournaments, without
- * prior permission from the authors.
- *
- * No responsibility is taken for any errors or inaccuracies inherent
- * either to the comments or the code of this program, but if reported
- * (see README file), then an attempt will be made to fix them.
- */
-
- #include "reve.h"
- #include "color.h"
- #include "extern.h"
- #include "images.h"
- #include <ctype.h>
- #include <limits.h>
- #include <signal.h>
- #include <sys/param.h>
- //#include <sys/time.h>
-
- #ifdef HASPOLL
- #include <poll.h>
- #endif /*HASPOLL*/
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xatom.h>
- #include <X11/Xos.h>
- #include <X11/cursorfont.h>
- #include <X11/keysym.h>
- #include <X11/Xresource.h>
-
- #define SOCK_INPUT 0 /* Types of input selected on. */
- #define COMP_INPUT 1
- #define DPY_INPUT 2
-
- #define BOARDFONT "lucidasanstypewriter-10"
- #define BOLDFONT "lucidasanstypewriter-bold-12"
- #define DEFFONT "fixed"
- #define HELPFONT "lucidasanstypewriter-10"
- #define NORMALFONT "lucidasanstypewriter-12"
-
- #define FRAME_MASK (ButtonPressMask | ButtonReleaseMask | ExposureMask | \
- EnterWindowMask | KeyPressMask | LeaveWindowMask | \
- PointerMotionMask | StructureNotifyMask)
-
- #define BORDER_SIZE 6
- #define LABEL_SIZE 27
- #define REVE_BORDER_WIDTH 2
-
- enum gr_type gtype = GX11 ; /* Graphics type. */
-
- static void get_event P(()) ;
- static void load_colors P(()) ;
-
- static int process_expose P((XExposeEvent *)) ;
-
- static Window get_wtype P((enum win_type)) ;
-
- Pixmap load_image P((unsigned char *)) ;
- Window make_subwindow P((int, int, int, int,
- char *, char *, int, char **)) ;
- XFontStruct *get_font P((char *, char *)) ;
-
- Atom protocol_atom, kill_atom ;
- Cursor cursor[MAXCURSORS] ;
- Display *dpy ;
- GC gc ; /* Graphics context for text and lines. */
- GC igc ; /* Graphics content for 1bit images. */
- GC ropgc ; /* Graphics context for rops. */
- GC stencilgc ; /* Graphics context for stencils. */
- Pixmap images[MAXIMAGES], no_pixmap, reve_icon ;
-
- Visual *visual ; /* Default visual for this display. */
- Window cframe ; /* Control panel frames. */
- Window gframe ; /* Game board frames. */
- Window hframe ; /* Help window frames. */
- Window pframe ; /* Property window frames. */
- Window root ;
-
- XClassHint class_hint = { "reve", "Reve" } ;
- XColor BGcolor, FGcolor ;
- XEvent event ;
- XFontStruct *font[MAXFONTS] ;
- XrmDatabase reve_DB ; /* Combined resources database. */
- XSizeHints size ;
- XWMHints wm_hints ;
- XGCValues gc_val ; /* Used to setup graphics context values. */
- int gc_flags ; /* Used to set up graphics context flags. */
- int screen ; /* Default graphics display screen. */
- int xfd ; /* Server connection file descriptors. */
- unsigned long backgnd ; /* Default background color. */
- unsigned long foregnd ; /* Default foreground color. */
- unsigned long gc_mask ; /* Mask for setting graphic context values. */
- unsigned long palette[REVE_COLORSIZE] ; /* Xlib color palette. */
-
- #ifdef NOSELECT
- #ifdef HASPOLL
- struct pollfd pfd[3] ;
- unsigned long npfd ; /* Number of file descriptors to monitor. */
- #endif /*HASPOLL*/
- #else /*NOSELECT*/
- #ifdef NO_43SELECT
- int fullmask ; /* Full mask of file descriptors to check on. */
- int readmask ; /* Readmask used in select call. */
- #else
- fd_set fullmask ; /* Full mask of file descriptors to check on. */
- fd_set readmask ; /* Readmask used in select call. */
- #endif /*NO_43SELECT*/
- #endif /*NOSELECT*/
-
- int opvals[3] ; /* Pixrect rasterop values. */
- unsigned int scr_depth ;
-
-
- /*ARGSUSED*/
- void
- batch(state) /* Turn graphics batching on or off. */
- enum bltype state ;
- {
- XFlush(dpy) ;
- }
-
-
- void
- beep()
- {
- XBell(dpy, 56) ;
- XFlush(dpy) ;
- }
-
-
- void
- close_reve()
- {
- XEvent event ;
-
- event.xclient.type = ClientMessage ;
- event.xclient.display = dpy ;
- event.xclient.window = gframe ;
- event.xclient.message_type = XInternAtom(dpy, "WM_CHANGE_STATE", False) ;
- event.xclient.format = 32 ;
- event.xclient.data.l[0] = IconicState ;
- XSendEvent(dpy, DefaultRootWindow(dpy), False,
- SubstructureRedirectMask | SubstructureNotifyMask, &event) ;
- XFlush(dpy) ;
- }
-
-
- void
- color_area(wtype, x, y, width, height, color)
- enum win_type wtype ;
- int x, y, width, height, color ;
- {
- Window window = get_wtype(wtype) ;
-
- if (iscolor) gc_val.foreground = palette[color] ;
- else
- {
- if (color == C_WHITE) gc_val.foreground = backgnd ;
- else gc_val.foreground = foregnd ;
- }
- gc_val.function = GXcopy ;
- XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
- XFillRectangle(dpy, window, gc, x, y,
- (unsigned int) width, (unsigned int) height) ;
- }
-
-
- void
- connect_io() /* Connect to X server, computer process and remote human. */
- {
- #ifdef NOSELECT
- #ifdef HASPOLL
- npfd = 0L ;
- pfd[0].fd = pfd[1].fd = pfd[2].fd = -1 ;
- pfd[0].events = pfd[1].events = pfd[2].events = POLLIN ;
- pfd[0].fd = xfd, npfd++ ; /* X server. */
- if (pipe_io[1][0] > 0) pfd[1].fd = pipe_io[1][0], npfd++ ; /* Computer. */
- if (socketfd > 0) pfd[2].fd = socketfd, npfd++ ; /* Human. */
- #endif /*HASPOLL*/
- #else
- #ifdef NO_43SELECT
- fullmask = 0 ;
- fullmask |= (1 << xfd) ; /* X server. */
- if (pipe_io[1][0] > 0) fullmask |= (1 << pipe_io[1][0]) ; /* Computer. */
- if (socketfd > 0) fullmask |= (1 << socketfd) ; /* Human. */
- #else
- FD_ZERO(&fullmask) ;
- FD_SET(xfd, &fullmask) ; /* X server. */
- if (pipe_io[1][0] > 0) FD_SET(pipe_io[1][0], &fullmask) ; /* Computer. */
- if (socketfd > 0) FD_SET(socketfd, &fullmask) ; /* Human. */
- #endif /*NO_43SELECT*/
- #endif /*NOSELECT*/
- }
-
-
- void
- destroy_reve() /* Terminate reve. */
- {
- KILL(pid, SIGKILL) ;
- XDestroyWindow(dpy, gframe) ;
- exit(0) ;
- }
-
-
- void
- draw_image(wtype, x, y, width, height, image)
- enum win_type wtype ;
- int x, y, width, height ;
- enum image_type image ;
- {
- Window window = get_wtype(wtype) ;
-
- gc_mask = GCStipple | GCTileStipXOrigin | GCTileStipYOrigin ;
- gc_val.stipple = images[(int) image] ;
- gc_val.ts_x_origin = x ;
- gc_val.ts_y_origin = y ;
- XChangeGC(dpy, ropgc, gc_mask, &gc_val) ;
- XFillRectangle(dpy, window, ropgc, x, y, width, height) ;
- }
-
-
- void
- draw_line(wtype, x1, y1, x2, y2, op, color)
- enum win_type wtype ;
- int x1, y1, x2, y2, color ;
- enum optype op ;
- {
- Window window = get_wtype(wtype) ;
-
- if (iscolor) gc_val.foreground = palette[color] ;
- else
- {
- if (color == C_WHITE) gc_val.foreground = backgnd ;
- else gc_val.foreground = foregnd ;
- }
- gc_val.function = opvals[(int) op] ;
- XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
- XDrawLine(dpy, window, gc, x1, y1, x2, y2) ;
- }
-
-
- void
- draw_stencil(wtype, x, y, width, height, op, color, stencil, image)
- enum win_type wtype ;
- int x, y, width, height, color ;
- enum optype op ;
- enum image_type stencil, image ;
- {
- Window window = get_wtype(wtype) ;
-
- if (iscolor) gc_val.foreground = palette[color] ;
- else gc_val.foreground = foregnd ;
- gc_val.function = opvals[(int) op] ;
- gc_val.clip_x_origin = x ;
- gc_val.clip_y_origin = y ;
- gc_val.clip_mask = images[(int) stencil] ;
- gc_val.stipple = images[(int) image] ;
- gc_val.ts_x_origin = x ;
- gc_val.ts_y_origin = y ;
- gc_mask = GCForeground | GCFunction | GCClipMask |
- GCClipXOrigin | GCClipYOrigin |
- GCStipple | GCTileStipXOrigin | GCTileStipYOrigin ;
- XChangeGC(dpy, stencilgc, gc_mask, &gc_val) ;
- XFillRectangle(dpy, window, stencilgc, x, y, width, height) ;
- }
-
-
- void
- draw_text(wtype, x, y, ftype, color, str)
- enum win_type wtype ;
- enum font_type ftype ;
- int x, y, color ;
- char *str ;
- {
- Window window = get_wtype(wtype) ;
-
- if (iscolor) gc_val.foreground = palette[color] ;
- else
- {
- if (color == C_WHITE) gc_val.foreground = backgnd ;
- else gc_val.foreground = foregnd ;
- }
- gc_val.font = font[(int) ftype]->fid ;
- gc_val.function = GXcopy ;
- XChangeGC(dpy, gc, GCFont | GCForeground | GCFunction, &gc_val) ;
- XDrawString(dpy, window, gc, x, y, str, strlen(str)) ;
- }
-
-
- static void
- get_event() /* Get the next canvas event. */
- {
- XSync(dpy, 0) ;
- if (!XCheckMaskEvent(dpy, ExposureMask, &event))
- XNextEvent(dpy, &event) ;
- }
-
-
- XFontStruct *
- get_font(name, defname)
- char *name, *defname ;
- {
- XFontStruct *f ;
-
- if (name == NULL || !(f = XLoadQueryFont(dpy, name)))
- if (!(f = XLoadQueryFont(dpy, defname)))
- if (!(f = XLoadQueryFont(dpy, DEFFONT)))
- {
- FPRINTF(stderr, "%s: couldn't get the default font.", progname) ;
- exit(1) ;
- }
- return(f) ;
- }
-
-
- char *
- get_resource(rtype) /* Get Reve resource from merged databases. */
- enum res_type rtype ;
- {
- char cstr[MAXLINE], nstr[MAXLINE], str[MAXLINE] ;
- char *str_type[20] ;
- XrmValue value ;
-
- STRCPY(str, resources[(int) rtype]) ;
- SPRINTF(nstr, "reve.%s", str) ;
- if (islower(str[0])) str[0] = toupper(str[0]) ;
- SPRINTF(cstr, "Reve.%s", str) ;
- if (XrmGetResource(reve_DB, nstr, cstr, str_type, &value) == NULL)
- return((char *) NULL) ;
- else return(value.addr) ;
- }
-
-
- int
- get_strwidth(ftype, str) /* Get width in pixels of string value. */
- enum font_type ftype ;
- char *str ;
- {
- return(XTextWidth(font[(int) ftype], str, strlen(str))) ;
- }
-
-
- static Window
- get_wtype(wtype)
- enum win_type wtype ;
- {
- if (wtype == W_BOARD) return(gframe) ;
- else if (wtype == W_PANEL) return(cframe) ;
- else if (wtype == W_PROPS) return(pframe) ;
- else if (wtype == W_HELP) return(hframe) ;
- }
-
-
- void
- init_fonts() /* Open the normal and bold fonts. */
- {
- int i ;
-
- font[(int) BFONT] = get_font(fontnames[(int) BFONT], BOLDFONT) ;
- font[(int) GFONT] = get_font(fontnames[(int) GFONT], BOARDFONT) ;
- font[(int) HFONT] = get_font(fontnames[(int) HFONT], HELPFONT) ;
- font[(int) NFONT] = get_font(fontnames[(int) NFONT], NORMALFONT) ;
-
- for (i = 0; i < MAXFONTS; i++)
- font_heights[i] = font[i]->max_bounds.ascent +
- font[i]->max_bounds.descent ;
- }
-
-
- /*ARGSUSED*/
- void
- init_graphics(argc, argv)
- int *argc ;
- char *argv[] ;
- {
- if ((dpy = XOpenDisplay(display)) == NULL)
- {
- FPRINTF(stderr,"%s: Couldn't open display %s\n", progname, display) ;
- exit(1) ;
- }
- xfd = ConnectionNumber(dpy) ;
- reve_DB = NULL ;
- igc = NULL ;
- }
-
-
- int
- init_ws_type()
- {
- screen = DefaultScreen(dpy) ;
- visual = DefaultVisual(dpy, screen) ;
- root = RootWindow(dpy, screen) ;
-
- if (!geometry) STRCPY(geometry, XGetDefault(dpy, progname, "Geometry")) ;
-
- foregnd = BlackPixel(dpy, screen) ;
- backgnd = WhitePixel(dpy, screen) ;
- scr_depth = DefaultDepth(dpy, screen) ;
-
- cursor[(int) CANVASCUR] = XCreateFontCursor(dpy, XC_top_left_arrow) ;
- cursor[(int) HOURGLASS] = XCreateFontCursor(dpy, XC_watch) ;
- no_pixmap = XCreateBitmapFromData(dpy, root, (char *) nocur_bits, 16, 16) ;
- cursor[(int) NOCURSOR] = XCreatePixmapCursor(dpy, no_pixmap, no_pixmap,
- &FGcolor, &BGcolor, 0, 0) ;
-
- gtype = GX11 ; /* Graphics type. */
- move_delta = 10 ;
-
- if (xdebug == TRUE) XSynchronize(dpy, TRUE) ;
- images[(int) BUT_STENCIL] = load_image(Sbutton_bits) ;
- images[(int) BUT_INVERT] = load_image(Ibutton_bits) ;
- images[(int) BUT_NORMAL] = load_image(Nbutton_bits) ;
- images[(int) CY_NORMAL] = load_image(Ncycle_bits) ;
- images[(int) CY_STENCIL] = load_image(Scycle_bits) ;
- images[(int) CY_LINVERT] = load_image(Lcycle_bits) ;
- images[(int) CY_RINVERT] = load_image(Rcycle_bits) ;
- images[(int) TOGGLE_ON] = load_image(Sch_on_bits) ;
- images[(int) TOGGLE_OFF] = load_image(Sch_off_bits) ;
- images[(int) P_WHITE] = load_image(white_bits) ;
- images[(int) P_BLACK] = load_image(black_bits) ;
- images[(int) S_MOVE] = load_image(move_bits) ;
- images[(int) S_SUGGEST] = load_image(suggest_bits) ;
-
- return(0) ;
- }
-
-
- static void
- load_colors() /* Create and load reve color map. */
- {
- XColor ccol ;
- int i, numcolors ;
-
- iscolor = 0 ;
- if (DisplayCells(dpy, screen) > 2)
- {
- iscolor = 1 ;
- numcolors = 0 ;
- for (i = 0; i < REVE_USEDCOLORSIZE; i++)
- {
- if (colstr[i] == NULL ||
- (XParseColor(dpy, DefaultColormap(dpy, screen),
- colstr[i], &ccol) == 0))
- {
- ccol.flags = DoRed | DoGreen | DoBlue ;
- ccol.red = (unsigned short) (rcols[i] << 8) ;
- ccol.green = (unsigned short) (gcols[i] << 8) ;
- ccol.blue = (unsigned short) (bcols[i] << 8) ;
- }
- if (XAllocColor(dpy,
- DefaultColormap(dpy, screen), &ccol) == True)
- palette[numcolors++] = ccol.pixel ;
- }
- if (numcolors < REVE_USEDCOLORSIZE)
- {
- FPRINTF(stderr, "%s: cannot allocate colors.\n", progname) ;
- exit(1) ;
- }
- }
- }
-
-
- Pixmap
- load_image(cbuf)
- unsigned char cbuf[] ;
- {
- Pixmap pixmap ;
-
- if (igc == NULL)
- {
- pixmap = XCreatePixmap(dpy, root, 64, 64, 1) ;
- gc_mask = GCForeground | GCBackground | GCGraphicsExposures ;
- gc_val.foreground = foregnd ;
- gc_val.background = backgnd ;
- gc_val.graphics_exposures = False ;
- igc = XCreateGC(dpy, pixmap, gc_mask, &gc_val) ;
- }
- return(XCreatePixmapFromBitmapData(dpy, root, (char *) cbuf,
- 64, 64, 1, 0, 1)) ;
- }
-
-
- /* Get the resource databases. These are looked for in the following ways:
- *
- * Classname file in the app-defaults directory. In this case, Classname
- * is Reve.
- *
- * Classname file in the directory specified by the XUSERFILESEARCHPATH
- * or XAPPLRESDIR environment variable.
- *
- * Property set using xrdb, accessible through the XResourceManagerString
- * macro or, if that is empty, the ~/.Xdefaults file.
- *
- * XENVIRONMENT environment variable or, if not set, .Xdefaults-hostname
- * file.
- *
- * REVEDEFAULTS environment variable or, if not set, the ~/.reverc file.
- */
-
- void
- load_resources()
- {
- XrmDatabase db ;
- char *home, name[_POSIX_PATH_MAX], *ptr ;
- int len ;
-
- home = getenv("HOME") ;
- XrmInitialize() ;
- STRCPY(name, "/usr/lib/X11/app-defaults/Reve") ;
-
- /* Get applications defaults file, if any. */
-
- db = XrmGetFileDatabase(name) ;
- XrmMergeDatabases(db, &reve_DB) ;
-
- /* Merge server defaults, created by xrdb. If nor defined, use ~/.Xdefaults. */
-
- #ifndef X11R3
- if (XResourceManagerString(dpy) != NULL)
- db = XrmGetStringDatabase(XResourceManagerString(dpy)) ;
- else
- #endif /*X11R3*/
- {
- SPRINTF(name, "%s/.Xdefaults", home) ;
- db = XrmGetFileDatabase(name) ;
- }
- XrmMergeDatabases(db, &reve_DB) ;
-
- /* Open XENVIRONMENT file or, if not defined, the .Xdefaults, and merge
- * into existing database.
- */
-
- if ((ptr = getenv("XENVIRONMENT")) == NULL)
- {
- SPRINTF(name, "%s/.Xdefaults-", home) ;
- len = strlen(name) ;
- GETHOSTNAME(name+len, _POSIX_PATH_MAX-len) ;
- db = XrmGetFileDatabase(name) ;
- }
- else db = XrmGetFileDatabase(ptr) ;
- XrmMergeDatabases(db, &reve_DB) ;
-
- /* Finally merge in Reve defaults via REVEDEFAULTS or, if not defined, the
- * ~/.reverc file.
- */
-
- if ((ptr = getenv("REVEDEFAULTS")) == NULL)
- {
- SPRINTF(name, "%s/.reverc", home) ;
- db = XrmGetFileDatabase(name) ;
- }
- else db = XrmGetFileDatabase(ptr) ;
- XrmMergeDatabases(db, &reve_DB) ;
- }
-
-
- /*ARGSUSED*/
- void
- lock_screen(state) /* Turn graphics locking on or off - null routine. */
- enum bltype state ;
- {}
-
-
- void
- make_canvas() {} /* Null routine, see the make_frame routine. */
-
-
- void
- make_frame(argc, argv) /* Create reve window/icon. */
- int argc ;
- char *argv[] ;
- {
- unsigned int h, w ; /* Window dimensions. */
- int flags ;
- int x, y ; /* Window position. */
-
- opvals[(int) RCLR] = GXclear ;
- opvals[(int) RSRC] = GXcopy ;
- opvals[(int) RINV] = GXxor ;
-
- if (!monochrome) load_colors() ;
- reve_icon = load_image(reve_bits) ;
-
- size.flags = PPosition | PMinSize | PSize ;
- size.x = 0 ;
- size.y = 0 ;
- size.width = board_width ;
- size.height = board_height ;
- size.min_width = size.min_height = MINBOARDSIZE ;
-
- if (strlen(geometry))
- {
- flags = XParseGeometry(geometry, &x, &y, &w, &h) ;
- if (XValue & flags)
- {
- if (XNegative & flags)
- x = DisplayWidth(dpy, screen) + x - size.width ;
- size.flags |= USPosition ;
- size.x = x ;
- }
- if (YValue & flags)
- {
- if (YNegative & flags)
- y = DisplayHeight(dpy, screen) + y - size.height ;
- size.flags |= USPosition ;
- size.y = y ;
- }
- }
-
- gframe = XCreateSimpleWindow(dpy, root,
- size.x, size.y, size.width, size.height,
- REVE_BORDER_WIDTH, foregnd, backgnd) ;
-
- protocol_atom = XInternAtom(dpy, "WM_PROTOCOLS", False) ;
- kill_atom = XInternAtom(dpy, "WM_DELETE_WINDOW", False) ;
-
- XSetStandardProperties(dpy, gframe, "reve", "Board", reve_icon,
- argv, argc, &size) ;
- #ifndef X11R3
- XSetWMProtocols(dpy, gframe, &kill_atom, 1) ;
- #endif /*X11R3*/
-
- wm_hints.icon_x = ix ;
- wm_hints.icon_y = iy ;
- wm_hints.input = True ;
- wm_hints.icon_pixmap = reve_icon ;
- wm_hints.flags = InputHint | IconPixmapHint ;
- if (iconic)
- {
- wm_hints.initial_state = IconicState ;
- wm_hints.flags |= StateHint ;
- }
- XSetWMHints(dpy, gframe, &wm_hints) ;
-
- /* Set XA_WM_CLASS so things that depend on NAME work. */
-
- XSetClassHint(dpy, gframe, &class_hint) ;
-
- /* Create control panel. */
-
- cframe = make_subwindow(0, board_height + BORDER_SIZE + LABEL_SIZE,
- PANEL_WIDTH, PANEL_HEIGHT,
- "reve", "Control", argc, argv) ;
- XSetWMHints(dpy, cframe, &wm_hints) ;
-
- /* Create property window. */
-
- pframe = make_subwindow(board_width + (2 * BORDER_SIZE), 0,
- PROPS_WIDTH, PROPS_HEIGHT,
- "reve properties", "Props", argc, argv) ;
-
- /* Create graphics contexts. */
-
- gc_mask = GCForeground | GCBackground | GCGraphicsExposures ;
- gc_val.foreground = foregnd ;
- gc_val.background = backgnd ;
- gc_val.graphics_exposures = False ;
- gc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
-
- ropgc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
- XSetFillStyle(dpy, ropgc, FillStippled) ;
-
- stencilgc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
- XSetFillStyle(dpy, stencilgc, FillOpaqueStippled) ;
-
- pid = fork_child() ;
- }
-
-
- void
- make_help_window(argc, argv)
- int argc ;
- char *argv[] ;
- {
- int fontwidth ;
-
- fontwidth = font[(int) HFONT]->max_bounds.rbearing +
- font[(int) HFONT]->min_bounds.lbearing ;
- help_height = ((font_heights[(int) HFONT] + 1) * HELP_ROWS) +
- (4 * CGAP) + CHEIGHT ;
- help_width = (fontwidth * HELP_COLS) + (2 * CGAP) ;
-
- hframe = make_subwindow(board_width + (2 * BORDER_SIZE), 0,
- help_width, help_height,
- "reve help", "Help", argc, argv) ;
- }
-
-
- void
- make_icon() {} /* Null routine - icon created in make_frame. */
-
-
- void
- make_pieces(width, height)
- int width, height ;
- {
- bborder = BBORDER ;
-
- cell_width = (width - (2 * bborder)) / BOARD_SIZE ;
- cell_height = (height - (2 * bborder)) / BOARD_SIZE ;
-
- pieceXmargin = cell_width / 8 ;
- pieceYmargin = cell_height / 8 ;
-
- pieceXrad = (cell_width - (2 * pieceXmargin)) / 2 ;
- if (pieceXrad > MAXPRAD)
- {
- pieceXrad = MAXPRAD ;
- pieceXmargin = (cell_width - (2 * pieceXrad)) / 2 ;
- }
-
- pieceYrad = (cell_height - (2 * pieceYmargin)) / 2 ;
- if (pieceYrad > MAXPRAD)
- {
- pieceYrad = MAXPRAD ;
- pieceYmargin = (cell_height - (2 * pieceYrad)) / 2 ;
- }
-
- XSetFunction(dpy, igc, GXclear) ;
- XCopyArea(dpy, images[(int) P_WHITE], images[(int) P_WHITE], igc,
- 0, 0, 2 * MAXPRAD, 2 * MAXPRAD, 0, 0) ;
- XCopyArea(dpy, images[(int) P_BLACK], images[(int) P_BLACK], igc,
- 0, 0, 2 * MAXPRAD, 2 * MAXPRAD, 0, 0) ;
-
- XSetFunction(dpy, igc, GXset) ;
- XDrawArc(dpy, images[(int) P_WHITE], igc,
- 0, 0, 2 * pieceXrad - 1, 2 * pieceYrad - 1, 0, 360 * 64) ;
- XFillArc(dpy, images[(int) P_BLACK], igc,
- 0, 0, 2 * pieceXrad - 1, 2 * pieceYrad - 1, 0, 360 * 64) ;
- }
-
-
- Window
- make_subwindow(x, y, width, height, wname, iname, argc, argv)
- int argc, x, y, width, height ;
- char *wname, *iname, *argv[] ;
- {
- Window w ;
-
- size.flags = PMinSize | PMaxSize | PPosition | PSize ;
- size.x = x ;
- size.y = y ;
- size.max_width = size.min_width = size.width = width ;
- size.max_height = size.min_height = size.height = height ;
-
- w = XCreateSimpleWindow(dpy, root, size.x, size.y,
- size.max_width, size.max_height,
- REVE_BORDER_WIDTH, foregnd, backgnd) ;
-
- XSetStandardProperties(dpy, w, wname, iname, reve_icon, argv, argc, &size) ;
- #ifndef X11R3
- XSetWMProtocols(dpy, w, &kill_atom, 1) ;
- #endif /*X11R3*/
- XSetTransientForHint(dpy, w, gframe) ;
- return(w) ;
- }
-
-
- void
- open_reve()
- {
- XMapWindow(dpy, gframe) ;
- }
-
-
- void
- process_event() /* Determine event type. */
- {
- XClientMessageEvent *ev ;
- XConfigureEvent *con ;
- XKeyPressedEvent *key_event ;
- KeySym keysym ;
- char chs[2] ;
-
- nextc = IGNORE_EVENT ;
- if (event.xany.window == gframe) curwin = W_BOARD ;
- else if (event.xany.window == cframe) curwin = W_PANEL ;
- else if (event.xany.window == pframe) curwin = W_PROPS ;
- else if (event.xany.window == hframe) curwin = W_HELP ;
-
- switch (event.type)
- {
- case ClientMessage : /* Catch ICCCM kill from WM. */
-
- ev = (XClientMessageEvent *) &event ;
- if (ev->message_type == protocol_atom &&
- ev->data.l[0] == kill_atom)
- {
- if (curwin == W_BOARD) destroy_reve() ;
- else if (curwin == W_HELP)
- {
- help_showing = FALSE ;
- XUnmapWindow(dpy, event.xany.window) ;
- }
- else if (curwin == W_PROPS)
- {
- props_showing = FALSE ;
- XUnmapWindow(dpy, event.xany.window) ;
- }
- }
- nextc = IGNORE_EVENT ;
- break ;
-
- case ConfigureNotify : con = (XConfigureEvent *) & event ;
- if (curwin == W_BOARD &&
- (board_width != con->width ||
- board_height != con->height))
- {
- board_width = con->width ;
- board_height = con->height ;
- make_pieces(board_width, board_height) ;
- paint_board() ;
- }
- break ;
-
- case Expose : nextc = process_expose((XExposeEvent *) &event) ;
- break ;
-
- case KeyPress : key_event = (XKeyPressedEvent *) &event ;
- curx = key_event->x ;
- cury = key_event->y ;
- (void) XLookupString(key_event, chs, 1,
- &keysym,
- (XComposeStatus *) NULL) ;
- if (keysym == XK_Shift_L ||
- keysym == XK_Shift_R) nextc = IGNORE_EVENT ;
- else
- {
- cur_ch = chs[0] ;
- nextc = KEYBOARD ;
- }
- break ;
-
- case EnterNotify : nextc = ENTER_WINDOW ;
- break ;
-
- case LeaveNotify : nextc = EXIT_WINDOW ;
- break ;
-
- case MotionNotify : if (processing == FALSE)
- {
- nextc = MOUSE_MOVING ;
- curx = event.xbutton.x ;
- cury = event.xbutton.y ;
- }
- break ;
-
- case ButtonPress : curx = event.xbutton.x ;
- cury = event.xbutton.y ;
- if (event.xbutton.button == Button1)
- nextc = LEFT_DOWN ;
- else if (event.xbutton.button == Button2)
- nextc = MIDDLE_DOWN ;
- else if (event.xbutton.button == Button3)
- nextc = RIGHT_DOWN ;
- break ;
-
- case ButtonRelease : curx = event.xbutton.x ;
- cury = event.xbutton.y ;
- if (event.xbutton.button == Button1)
- nextc = LEFT_UP ;
- else if (event.xbutton.button == Button2)
- nextc = MIDDLE_UP ;
- else if (event.xbutton.button == Button3)
- nextc = RIGHT_UP ;
- }
- }
-
-
- static int
- process_expose(event)
- XExposeEvent *event ;
- {
- int docframe, dogframe, dohframe, dopframe ;
-
- docframe = dogframe = dohframe = dopframe = 0 ;
- do
- {
- if (event->count == 0 && event->window == gframe) dogframe++ ;
- if (event->count == 0 && event->window == cframe) docframe++ ;
- if (event->count == 0 && event->window == pframe) dopframe++ ;
- if (event->count == 0 && event->window == hframe) dohframe++ ;
- }
- while (XCheckMaskEvent(dpy, ExposureMask, (XEvent *) event)) ;
-
- /* Events handled here, in case of multiple simultaneous occurances. */
-
- if (dogframe) paint_board() ;
- if (docframe) paint_panel() ;
- if (dohframe) paint_help() ;
- if (dopframe) paint_prop_sheet() ;
- return(IGNORE_EVENT) ;
- }
-
-
- void
- raise_reve()
- {
- XRaiseWindow(dpy, gframe) ;
- }
-
-
- void
- set_cursor(ctype)
- enum curtype ctype ;
- {
- XDefineCursor(dpy, gframe, cursor[(int) ctype]) ;
- XDefineCursor(dpy, cframe, cursor[(int) ctype]) ;
- XDefineCursor(dpy, hframe, cursor[(int) ctype]) ;
- XDefineCursor(dpy, pframe, cursor[(int) ctype]) ;
- XFlush(dpy) ;
- }
-
-
- void
- set_frame(wtype, showing)
- enum win_type wtype ;
- int showing ;
- {
- Window window ;
-
- if (wtype == W_HELP) window = hframe ;
- else if (wtype == W_PROPS) window = pframe ;
-
- if (showing) XMapWindow(dpy, window) ;
- else XUnmapWindow(dpy, window) ;
- }
-
-
- void
- show_windows()
- {
- XSelectInput(dpy, gframe, FRAME_MASK) ;
- XSelectInput(dpy, cframe, FRAME_MASK) ;
- XSelectInput(dpy, hframe, FRAME_MASK) ;
- XSelectInput(dpy, pframe, FRAME_MASK) ;
-
- XMapWindow(dpy, gframe) ;
- XMapWindow(dpy, cframe) ;
- if (help_showing) XMapWindow(dpy, hframe) ;
- if (props_showing) XMapWindow(dpy, pframe) ;
- }
-
-
- void
- start_tool(dtype) /* Start event dispatcher and display. */
- enum disp_type dtype ;
- {
- int fd ; /* Type of this input. */
- struct timeval tval ; /* Set to go off, once a second. */
-
- show_windows() ;
- tval.tv_usec = 0 ;
- tval.tv_sec = 1 ;
- for (;;)
- {
- XFlush(dpy) ;
- #ifdef NOSELECT
- #ifdef HASPOLL
- fd = -1 ;
- POLL(pfd, npfd, -1) ;
- if (pfd[0].revents == POLLIN) fd = DPY_INPUT ;
- else if (pfd[1].revents == POLLIN) fd = COMP_INPUT ;
- else if (pfd[2].revents == POLLIN) fd = SOCK_INPUT ;
- #else
- fd = 0 ;
- #endif /*HASPOLL*/
- #else
- fd = -1 ;
- readmask = fullmask ;
- #ifdef NO_43SELECT
- SELECT(32, &readmask, 0, 0, &tval) ;
- if (readmask && (1 << xfd)) fd = DPY_INPUT ;
- else if (readmask && (1 << pipe_io[1][0])) fd = COMP_INPUT ;
- else if (readmask && (1 << socketfd)) fd = SOCK_INPUT ;
- #else
- SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &tval) ;
- if (FD_ISSET(xfd, &readmask)) fd = DPY_INPUT ;
- else if (FD_ISSET(pipe_io[1][0], &readmask)) fd = COMP_INPUT ;
- else if (FD_ISSET(socketfd, &readmask)) fd = SOCK_INPUT ;
- #endif /*NO_43SELECT*/
- #endif /*NOSELECT*/
-
- switch (fd)
- {
- case DPY_INPUT : while (XPending(dpy))
- {
- get_event() ;
- handle_event() ;
- }
- break ;
- #ifdef REMOTE_PLAYER
- case SOCK_INPUT : read_from_sock(socketfd) ; /* Remote human. */
- break ;
- #endif /* REMOTE_PLAYER */
- case COMP_INPUT : read_from_reve(pipe_io[1][0]) ; /* Computer. */
- }
- if (cmode != GAME_OVER) update_clock(next_player, FALSE) ;
- }
- }
-